﻿using Kn.DLMS;
using Kn.DLMS.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using WindowsFormsApplication3;

namespace Kn.ALICE
{
    #region  信道配置参数 基类
    public class GXAliceChannelConfig
    {

        public ushort Code { get; set; }   //编码
        public ushort Len { get; set; }   //长度
        public string Name { get; set; }         // 名称
        public string strUIParseResult = "";   //解析结果
        public GXByteBuffer ParaBuf = new GXByteBuffer();

        //GXByteBuffer ParaBuf = new GXByteBuffer();
        public virtual bool Parser()
        {
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    #region 0002逻辑连接协议
    public class Protocol
    {
        bool D0;// 使用TCP   0：不使用 1：使用
        bool D1;// 使用UDP   0：不使用 1：使用
        bool D2;// 使用PPP   0：不使用 1：使用
        bool D3;// 使用L2TP  0：不使用 1：使用
        bool D4;// 使用IPSec 0：不使用 1：使用
        bool D5;// 使用PPTP  0：不使用 1：使用
                //其他：保留，置0
        public ushort D16;

        public string UIParserResult { get; set; }

        public  bool Parser()
        {
            try
            {
                D0 = ((D16 & 0x0001) == 0x0001);
                D1 = ((D16 & 0x0002) == 0x0002);
                D2 = ((D16 & 0x0004) == 0x0004);
                D3 = ((D16 & 0x0008) == 0x0008);
                D4 = ((D16 & 0x0010) == 0x0010);
                D5 = ((D16 & 0x0020) == 0x0020);

                if (D0) UIParserResult += "使用TCP, D0=1";
                if (D1) UIParserResult += "使用UDP, D1=1";
                if (D2) UIParserResult += "使用PPP, D2=1";
                if (D3) UIParserResult += "使用L2TP, D3=1";
                if (D4) UIParserResult += "使用IPSec, D4=1";
                if (D5) UIParserResult += "使用PPTP, D5=1";

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    public class GXGXAliceChannelConfig_0002 : GXAliceChannelConfig
    {
        #region 属性



        Protocol protocol { get; set; } = new Protocol();    


 
        #endregion

        public GXGXAliceChannelConfig_0002()
        {
            Code = 0x0002;
            Name = "信道配置参数编码0002";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();
                protocol.D16 = ParaBuf.GetUInt16();
                protocol.Parser();
                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(2) + Name + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 数据长度" + Len.ToString() + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + protocol.UIParserResult + "\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    #region 0004网络名称

    public class NetWord
    {
        public string strValue { get; set; }
        public byte[] byteValue { get; set; } = new byte[32];

        public bool Parser()
        {
            try
            {
                strValue = Encoding.ASCII.GetString(byteValue);
                strValue = strValue.Replace("\0", "");

                strValue = GXCommon.ReverseString(strValue);
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }



    public class GXGXAliceChannelConfig_0004 : GXAliceChannelConfig
    {
        #region 属性

        public NetWord netWord { get; set; } = new NetWord();
        #endregion

        public GXGXAliceChannelConfig_0004()
        {
            Code = 0x0004;
            Name = "信道配置参数编码0004";
        }


        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();
                ParaBuf.Get(netWord.byteValue);
                netWord.Parser();
                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(2) + Name + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 数据长度" + Len.ToString() + "\r\n";
                strUIParseResult += ParaBuf.GetString(32) + ": APN:" + netWord.strValue + "\r\n";


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }
    #endregion

    #region 0005用户名密码

    public class User
    {

        public string strNameValue     { get; set; }
        public string strPasswordValue { get; set; }

        public byte[] byteNameValue      { get; set; } = new byte[32];
        public byte[] bytePasswordValue  { get; set; } = new byte[32];


        public bool Parser()
        {
            try
            {
                strNameValue     = Encoding.ASCII.GetString(byteNameValue);
                strPasswordValue = Encoding.ASCII.GetString(bytePasswordValue);

                strNameValue = GXCommon.ReverseString(strNameValue);
                strPasswordValue = GXCommon.ReverseString(strPasswordValue);

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }


    }



    public class GXGXAliceChannelConfig_0005 : GXAliceChannelConfig
    {
        #region 属性
        public User user { get; set; } = new User();
        #endregion

        public GXGXAliceChannelConfig_0005()
        {
            Code = 0x0005;
            Name = "信道配置参数编码0005";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();
                ParaBuf.Get(user.byteNameValue);
                ParaBuf.Get(user.bytePasswordValue);
                user.Parser();
                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(2) + Name + "\r\n";
                strUIParseResult += ParaBuf.GetString(2)  + ": 数据长度"  + Len.ToString() + "\r\n";
                strUIParseResult += ParaBuf.GetString(32) + ": 用户名:  " + user.strNameValue + "\r\n";
                strUIParseResult += ParaBuf.GetString(32) + ": 密码: "    + user.strPasswordValue+ "\r\n";

            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }


    }
    #endregion

    #region 0006鉴权方式

    public class TokenAuth
    {
        public string strWayValue { get; set; }  //鉴权方式
        public byte byteWayValue { get; set; }    

        public byte KeyLen { get; set; }    
        public byte KeyFormat { get; set; }    
        public string strKeyFormat { get; set; }

        public byte[] byteKeyValue { get; set; }
        public string strKeyValue;
        public bool Parser()
        {
            try
            {
                if (byteWayValue == 0) strWayValue = "0:无鉴权";
                if (byteWayValue == 1) strWayValue = "1:PAP";
                if (byteWayValue == 2) strWayValue = "2:CHAP";
                if (byteWayValue == 3) strWayValue = "3:PAP & CHAP";
                if (byteWayValue == 0xFF) strWayValue = "0xFF:自动模式(默认PAP)";

                if (KeyFormat == 0) strKeyFormat = "0:不指定";
                if (KeyFormat == 1) strKeyFormat = "1:BCD";
                if (KeyFormat == 2) strKeyFormat = "2:BIN";
                if (KeyFormat == 3) strKeyFormat = "3:ASCII";

                if(KeyLen != 0)
                {
                    strKeyValue = Encoding.ASCII.GetString(byteKeyValue);
                }


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }


    public class GXGXAliceChannelConfig_0006 : GXAliceChannelConfig
    {
        #region 属性
        public TokenAuth tokenAuth { get; set; } = new TokenAuth();
        #endregion

        public GXGXAliceChannelConfig_0006()
        {
            Code = 0x0006;
            Name = "信道配置参数编码0006";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();

                tokenAuth.byteWayValue = ParaBuf.GetUInt8();
                tokenAuth.KeyLen = ParaBuf.GetUInt8();

                if(tokenAuth.KeyLen != 0)
                {
                    tokenAuth.KeyFormat = ParaBuf.GetUInt8();
                    tokenAuth.byteKeyValue = new byte[tokenAuth.KeyLen];
                    ParaBuf.Get(tokenAuth.byteKeyValue);
                }
                tokenAuth.Parser();

                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(2) + Name + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 数据长度:" + Len.ToString() + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 鉴权方式:" + tokenAuth.strWayValue + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 密钥长度:" + tokenAuth.KeyLen.ToString() + "\r\n";
                if(tokenAuth.KeyLen != 0)
                {
                    strUIParseResult += ParaBuf.GetString(2) + ": 密钥格式:" + tokenAuth.strKeyFormat + "\r\n";
                    strUIParseResult += ParaBuf.GetString(2) + ": 密钥:" + tokenAuth.strKeyValue + "\r\n";
                }


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion DE发送信道配置参数 DE发送信道配置参数

    #region 0008 TCP/IP连接模式
    public class GXGXAliceChannelConfig_0008 : GXAliceChannelConfig
    {
        #region 属性
        public Byte   WorkMode { get; set; }
        public string strWorkMode { get; set; }
        #endregion

        public GXGXAliceChannelConfig_0008()
        {
            Code = 0x0008;
            Name = "信道配置参数编码0008";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();

                WorkMode = ParaBuf.GetUInt8();
                if ((WorkMode & 0x01) == 0x01) strWorkMode = "D0:客户端模式";
                if ((WorkMode & 0x02) == 0x02) strWorkMode = "D1:端口侦听模式";

                ParaBuf.Position = 0;
                strUIParseResult += ParaBuf.GetString(2) + Name + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 数据长度:" + Len.ToString() + "\r\n";
                strUIParseResult += ParaBuf.GetString(1) + ": TCP/IP连接方式:" + strWorkMode + "\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }

    }
    #endregion

    #region 0009 PIN码

    public class PINCode
    {
        public byte IdentityInformation { get; set; }
        public byte bytePinLen { get; set; }

        public byte bytePinFormat { get; set; }
        public string strPinFormat { get; set; }

        public byte[] bytePinValue;
        public string stringPinValue;

        public bool Parser()
        {
            try
            {
                if (bytePinFormat == 1) strPinFormat = "1:BCD";
                if (bytePinFormat == 2) strPinFormat = "2:BIN";
                if (bytePinFormat == 3) strPinFormat = "3:ASCII";

                if (bytePinLen != 0)
                {
                    //stringPinValue = Encoding.ASCII.GetString(bytePinValue);
                }


            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }


    public class GXGXAliceChannelConfig_0009 : GXAliceChannelConfig
    {
        #region 属性
        public PINCode pinCode { get; set; } = new PINCode();
        #endregion

        public GXGXAliceChannelConfig_0009()
        {
            Code = 0x0009;
            Name = "信道配置参数编码0009";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();
                pinCode.IdentityInformation = ParaBuf.GetUInt8();
                pinCode.bytePinLen = ParaBuf.GetUInt8();
                pinCode.bytePinFormat = ParaBuf.GetUInt8();

                if (pinCode.bytePinLen != 0)
                {
                    pinCode.bytePinValue = new byte[pinCode.bytePinLen];
                    ParaBuf.Get(pinCode.bytePinValue);
                }
                pinCode.Parser();

                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(2) + Name + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 数据长度" + Len.ToString() + "\r\n";

                strUIParseResult += ParaBuf.GetString(1) + ": 身份信息集标志:  " + pinCode.IdentityInformation.ToString() + "\r\n";
                strUIParseResult += ParaBuf.GetString(1) + ": PIN码长度=:  " + pinCode.bytePinLen.ToString() + "\r\n";

                if(pinCode.bytePinLen != 0)
                {
                    strUIParseResult += ParaBuf.GetString(1) + ": PIN码格式=:  " + pinCode.strPinFormat + "\r\n";
                    strUIParseResult += ParaBuf.GetString(pinCode.bytePinLen) + ": PIN码" + "\r\n";
                }
                

            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

    }
    #endregion

    #region 000D IP地址和端口

    public class NetworkEndpoint
    {
        public byte[] ByteIpAddress { get; set; } = new byte[4];
        public byte[] BytePort { get; set; } = new byte[2];

        public string IpAddress { get; set; } // IP
        public int Port { get; set; } // 端口号


        public string ConvertToIPAddress(byte[] bytes)
        {
            if (bytes.Length != 4)
            {
                throw new ArgumentException("The byte array must contain exactly 4 bytes.");
            }

            string ipAddress = string.Join(".", bytes);
            return ipAddress;
        }

        public int ConvertToPort(byte[] bytes)
        {
            if (bytes.Length != 2)
            {
                throw new ArgumentException("The byte array must contain exactly 2 bytes.");
            }

            // 将字节序列转换为无符号短整型（ushort）
            ushort port = (ushort)((bytes[1] << 8) | bytes[0]);

            return port;
        }

        public bool Parser()
        {
            try
            {
                IpAddress = ConvertToIPAddress(ByteIpAddress);
                Port = ConvertToPort(BytePort);
            }
            catch (Exception ex)
            {
                return false;
            }
            // 可以在派生类中重写该方法
            return true;
        }
    }


    public class GXGXAliceChannelConfig_000D : GXAliceChannelConfig
    {

        #region 属性
        public NetworkEndpoint destination { get; set; } = new NetworkEndpoint();
        #endregion


        public GXGXAliceChannelConfig_000D()
        {
            Code = 0x000D;
            Name = "信道配置参数编码000D";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();

                ParaBuf.Get(destination.ByteIpAddress);
                ParaBuf.Get(destination.BytePort);
                destination.Parser();

                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(4) + ": 目标IP地址(IPv4) :" + destination.IpAddress + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 目标端口(IPv4) " + destination.Port.ToString() +  "\r\n";
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
    }
    #endregion

    #region 000E 主动上报
    public class GXGXAliceChannelConfig_000E : GXAliceChannelConfig
    {
        #region 属性
        public NetworkEndpoint notification { get; set; } = new NetworkEndpoint();
        #endregion

        public GXGXAliceChannelConfig_000E()
        {
            Code = 0x000E;
            Name = "信道配置参数编码000E";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();

                ParaBuf.Get(notification.ByteIpAddress);
                ParaBuf.Get(notification.BytePort);
                notification.Parser();

                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(4) + ": 主动上报 IP地址(IPv4) :" + notification.IpAddress + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 主动上报  端口(IPv4) " + notification.Port.ToString() + "\r\n";

            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
    }
    #endregion


    #region 0014 CU失联复位间隔
    public class GXGXAliceChannelConfig_0014 : GXAliceChannelConfig
    {
        #region 属性
        public ushort ModuleLostContactResetInterval; //单位 分钟
        #endregion

        public GXGXAliceChannelConfig_0014()
        {
            Code = 0x000E;
            Name = "信道配置参数编码0014";
        }

        public override bool Parser()
        {
            try
            {
                ParaBuf.Position = 0;
                Code = ParaBuf.GetUInt16();
                Len = ParaBuf.GetUInt16();
                ModuleLostContactResetInterval = ParaBuf.GetUInt16();

                ParaBuf.Position = 0;
                strUIParseResult = "";
                strUIParseResult += ParaBuf.GetString(4) + ": 主动上报 IP地址(IPv4) :" + notification.IpAddress + "\r\n";
                strUIParseResult += ParaBuf.GetString(2) + ": 主动上报  端口(IPv4) " + notification.Port.ToString() + "\r\n";

            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
    }
    #endregion
    public class GXAlicChannelConfigDictionary
    {
       
        //字段
        public Dictionary<ushort, GXAliceChannelConfig> ChannelConfigDictionary = new Dictionary<ushort, GXAliceChannelConfig>(30);

        public GXAlicChannelConfigDictionary()
        {
            GXAliceChannelConfig Config0002 = new GXGXAliceChannelConfig_0002();
            GXAliceChannelConfig Config0004 = new GXGXAliceChannelConfig_0004();
            GXAliceChannelConfig Config0005 = new GXGXAliceChannelConfig_0005();
            GXAliceChannelConfig Config0006 = new GXGXAliceChannelConfig_0006();
            GXAliceChannelConfig Config0008 = new GXGXAliceChannelConfig_0008();
            GXAliceChannelConfig Config0009 = new GXGXAliceChannelConfig_0009();
            GXAliceChannelConfig Config000D = new GXGXAliceChannelConfig_000D();
            GXAliceChannelConfig Config000E = new GXGXAliceChannelConfig_000E();


            ChannelConfigDictionary.Add(Config0002.Code, Config0002);
            ChannelConfigDictionary.Add(Config0004.Code, Config0004);
            ChannelConfigDictionary.Add(Config0005.Code, Config0005);
            ChannelConfigDictionary.Add(Config0006.Code, Config0006);
            ChannelConfigDictionary.Add(Config0008.Code, Config0008);
            ChannelConfigDictionary.Add(Config0009.Code, Config0009);
            ChannelConfigDictionary.Add(Config000D.Code, Config000D);
            ChannelConfigDictionary.Add(Config000E.Code, Config000E);
        }
    }
}